/**
* @program: src
*
* @description:ws服务接口
*
* @author: Mr.chen
*
* @create: 2020-11-05 13:33
**/
package wsconn
import (
	"ydd-im/service/api/models"
	"ydd-im/service/api/services/wsservice/account"
	"ydd-im/service/api/services/wsservice/client"
	"ydd-im/service/api/services/wsservice/message"
	"ydd-im/service/api/tools/response"
	"ydd-im/service/api/tools/util"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"net/http"
	"strconv"

	//"time"
)
const (
	// 最大的消息大小
	maxMessageSize = 8192
)

type Controller struct {
}

type renderData struct {
	ClientId string `json:"clientId"`
	Isconn int `json:"isconn"`
}

func (ws *Controller) Conn(c *gin.Context) {
	conn, err := (&websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		// 允许所有CORS跨域请求
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}).Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		fmt.Errorf("upgrade error: %v", err)
		http.NotFound(c.Writer,  c.Request)
	}
	//设置读取消息大小上线
	conn.SetReadLimit(maxMessageSize)
	//解析参数
	token := c.Request.FormValue("token")
	appkey := c.Request.FormValue("appkey")
	if len(token) == 0 {
		response.ResponseConnJsonRender(conn, response.WsData{
			Code:  response.ErrorCode,
			Message: "token不能为空",
		})
		_ = conn.Close()
		return
	}
	// 根据token 查询用户的信息，建立用户指定的数组
	userInfo,err := account.GetUserInfoByToken(token)
	if err != nil {
		response.ResponseConnJsonRender(conn, response.WsData{
			Code:  response.ErrorTokenCode,
			Message: err.Error(),
		})
		_ = conn.Close()
		return
	}
	userInfos,ok := userInfo.(models.User)
	fmt.Println(userInfos)
	if !ok {
		response.ResponseConnJsonRender(conn, response.WsData{
			Code:  response.ErrorTokenCode,
			Message: "查询用户信息有误",
		})
		_ = conn.Close()
		return
	}
	systemUsername,err := new(models.Signconfigure).GetSystemId(appkey,userInfos.Username) // 用户的唯一标识，userID太短，虽然唯一
	systemId := userInfos.Id
	if err != nil {
		response.ResponseConnJsonRender(conn, response.WsData{
			Code:  response.ErrorCode,
			Message: err.Error(),
		})
		_ = conn.Close()
		return
	}
	// 判断账号是否存在，不存在不能发送
	err = account.CheckisRegister(systemUsername) // 系统id为appky_username
	if err != nil {
		response.ResponseConnJsonRender(conn, response.WsData{
			Code:  response.ErrorTokenCode,
			Message: err.Error(),
		})
		_ = conn.Close()
		return
	}
	clientId := util.GenClientId() // 客户端ID,唯一
	clientSocket := client.NewClient(clientId, systemId, conn)
	//  systemId必须是唯一的，比如token,将系统id为下标，存储对应的客户端
	client.Manager.AddClientToSystemClient(systemId, clientSocket)
	//读取客户端消息
	clientSocket.Read()
	// 将token与clientid建立绑定关系
	if util.IsCluster() { // 如果是集群的
		err = account.AddClientToUser(userInfos.Id, clientId)
		if err != nil {
			response.ResponseConnJsonRender(conn, response.WsData{
				Code:    response.ErrorCode,
				Message: err.Error(),
			})
			_ = conn.Close()
			return
		}
	}
	//err = account.UpdateUserInfoByToken(token,clientId)
	//if err != nil {
	//	response.ResponseConnJsonRender(conn, response.WsData{
	//		Code:  response.ErrorCode,
	//		Message: err.Error(),
	//	})
	//	_ = conn.Close()
	//	return
	//}
	if err = response.ResponseConnJsonOk(conn, response.Response{
		Code:  response.SuccessCode,
		Message: "Ok",
		Data:renderData{ClientId: clientId,Isconn:1},
	}); err != nil {
		_ = conn.Close()
		return
	}
	// 发送用户连接事件
	client.Manager.Connect <- clientSocket
	// 更新记录为被挤下线状态
	//err = account.UpdateUserTokenState(userInfos.ClientId,userInfos.Id,"2")
	//if err != nil {
	//	response.ResponseConnJsonRender(conn, response.WsData{
	//		Code:  response.ErrorCode,
	//		Message: err.Error(),
	//	})
	//	_ = conn.Close()
	//	return
	//}
	// 发送用户下线功能
	//var data string ="data"
	//strdata := fmt.Sprintf("当前用户于%d:%d在其它地方登陆，如果不是本人登陆，请尽快修改密码",time.Now().Hour(),time.Now().Minute())
	//_ = client.SendMessageToUserClose(userInfos.ClientId,userInfos.Id,response.ErrorCloseCode,strdata,&strdata)
	// 查询用户未推送的信息，在线推送
	SendmessageList,err := message.GetMessageArriveJoinMessageList(userInfos.Id)
	if err != nil {
		response.ResponseConnJsonRender(conn, response.WsData{
			Code:    response.ErrorCode,
			Message: err.Error(),
		})
		_ = conn.Close()
		return
	}

	var messageList []map[string]string
	go func(SendmessageList []models.Message) {
		for k, _ := range SendmessageList {
			// 构建消息体
			messageData := response.MessageData{
				MessageLogId:SendmessageList[k].Id,
				ToUserId:SendmessageList[k].Dstid,
				Media:SendmessageList[k].Media,
				Pic:SendmessageList[k].Pic,
				Url:SendmessageList[k].Url,
				MessageType:SendmessageList[k].MessageType,
				SendTime:util.GetTimeDate(SendmessageList[k].Createtime),
				Content:SendmessageList[k].Content,
				SendUserId:SendmessageList[k].Userid,
				SendUsername:SendmessageList[k].Username,
				Dstid:SendmessageList[k].Dstid,
			}
			func(touserId int, sendUserId int, code int, msg string,messageData response.MessageData) {
				messageId := client.SendMessageToUserAndMine(touserId, sendUserId, code, msg,messageData)
				var messageMapList map[string]string = make(map[string]string, 0)
				messageMapList["messageId"] = messageId
				messageMapList["touserId"] = strconv.Itoa(touserId)
				messageMapList["sendUserId"] = strconv.Itoa(sendUserId)
				messageList = append(messageList,messageMapList)
			}(SendmessageList[k].Dstid, SendmessageList[k].Userid, response.SuccessCode,"Ok",messageData )

		}
	}(SendmessageList)
	fmt.Println(messageList)


}

